Crossposted to alt.hackers for obvious reasons..
In article <1993Apr29.1...@nuscc.nus.sg> eng2...@nusunix1.nus.sg (GOH LIU KANG) writes:
>Linus Torvalds (torv...@klaava.Helsinki.FI) wrote:
>: Filesystem: 30-char minix mainly. Some (very quick) tests with ext2fs
>: and xiafs when I upgraded the disks, but I like to use a filesystem that
>: I know well enough to edit by hand if I do something stupid (like delete
>: the kernel subdirectory by mistake - this happened once, and I was able
>: to get it all back by hacking 'fsck' to do it).
> ^^^^^^^^^^^^^^^^^^^^^^^
> Would you mind teach the world how:)
>Thanks a million.
Frankly, you don't want to know. I noticed what I did 5 seconds after I
did it (don't you always), and immediately unmounted the partition. The
actual fsck.c hacking was ugly enough to scare small children, and
roughly went like this:
- change fsck.c to print out all filenames found with the '-l' option,
even if the inode number in the directory entry is '0' (ie deleted).
Look for the name 'linux' (the name isn't removed from the directory,
only the inode number is cleared).
- make fsck also scan all unused directory inodes, and make it check
the first few entries in the directory - this way I found the 'linux'
directory inode.
- the above gave me the inode number of the recently deleted directory,
along with the slot the number should go into. Fill in the inode
number into the correct place. Now we have the 'linux' directory
back.
Ok so far - looks messy, doesn't it? In fact, that's all I needed to do,
as after that it's just a question of running 'fsck' (the normal one) to
correct all counts. Why? The files in the linux directory were also
deleted, so presumably I'd have to do the same for every file in the
tree, right?
Noho - the minix filesystem is clever enough to optimize away updates to
files that are deleted, so what happened with the original 'rm -rf' was
that although the directories were changed (zeroing out all the inode
numbers), the directories themselves were removed directly afterwards,
which means that the updated (zeroed) directory blocks were never
actually written to disk. So when I got the linux subdirectory back, it
automatically had all the correct inode numbers - and the inodes in
question only had the 'inode-in-use' bit cleared, so fsck happily
corrected those, counted the correct inode->i_links values, and updated
the disk.
What do we learn from this experience?
(a) synchronous directory updates aren't always a good idea: linux
doesn't do it, and there are moments when it's a good thing (people
may disagree with me, but I generally don't think you win very much
by making them synchronous, and you lose performance and hacks like
the above).
(b) if you know the system well enough, you can do things that aren't
supposed to be possible.
(c) Use backups - it's usually easier than hacking around the raw disk
for the lost data (but "real men" do it the hard way just to show
off, of course)
Linus